﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Effects;
using Workflow.Silverlight.Controls;
using System.Windows.Threading;
using System.Diagnostics;

namespace WorkflowDesigner.Workflow.Item
{
    public partial class FlowNormal : WorkflowBase
    {
        // 从中心的小圈圈出来的线条，供动态连线用
        protected ArrowLine m_lineTracking = null;
        // 正在从中心的小圈圈开始拖动鼠标
        protected bool m_isTrackingMouseMove = false;
        // Tooltip
        protected string m_strComment = null;

        // 默认的填充颜色
        protected Color m_clrText = Colors.Black;
        protected Color m_clrFocus = Colors.Yellow;
        protected Color m_clrMouseOver = Color.FromArgb(255, 240, 240, 240);
        protected Color m_clrNormal = Colors.White;
        protected Color m_clrShardow = Color.FromArgb(255, 100, 100, 100);
        // 默认的边框颜色
        protected Color m_clrBorder = Colors.Green;

        public FlowNormal()
        {
            InitializeComponent();
            OnInit();
        }

        /// <summary>
        /// 初始化窗口内容
        /// </summary>
        protected override void OnInit()
        {
            base.OnInit();

            #region 初始化界面元素
            // 内圈
            sNode.Stroke = new SolidColorBrush(m_clrBorder);
            sNode.Width = this.Width;
            sNode.Height = this.Height;
            sNode.Fill = new SolidColorBrush(m_clrNormal);

            // 阴影效果
            sNodeShadow.Width = this.Width;
            sNodeShadow.Height = this.Height;
            BlurEffect blur = new BlurEffect();
            blur.Radius = Utility.dBlurEffectRadius;
            sNodeShadow.Effect = blur;
            sNodeShadow.Fill = new SolidColorBrush(m_clrShardow);

            // 中心灰色连线区
            sNodeCenter.SetValue(Canvas.TopProperty, (sNodeShadow.Height - sNodeCenter.Height) / 2.0);
            sNodeCenter.SetValue(Canvas.LeftProperty, (sNodeShadow.Width - sNodeCenter.Width) / 2.0);

            // 文本区域
            txtLable.MaxWidth = this.Width;
            txtLable.Foreground = new SolidColorBrush(m_clrText);
            txtLable.SetValue(Canvas.TopProperty, (this.Height - txtLable.ActualHeight) / 2.0);
            txtLable.SetValue(Canvas.LeftProperty, (this.Width - txtLable.ActualWidth) / 2.0);

            this.SizeChanged += new SizeChangedEventHandler(Node_SizeChanged);

            sNodeShadow.SetValue(Canvas.ZIndexProperty, 1);
            sNode.SetValue(Canvas.ZIndexProperty, 2);
            txtLable.SetValue(Canvas.ZIndexProperty, 3);
            sNodeCenter.SetValue(Canvas.ZIndexProperty, 4);
            #endregion
        }

        public override FlowItemType ItemType
        {
            get
            {
                return FlowItemType.Normal;
            }
        }

        public override bool IsFocus
        {
            get
            {
                return m_isFocus;
            }
            set
            {
                m_isFocus = value;
                if (m_isFocus)
                {
                    // 焦点状态
                    sNodeShadow.Fill = new SolidColorBrush(m_clrFocus);
                    sNode.Fill = new SolidColorBrush(m_clrFocus);
                    App.theMainView.SetFlowItemFocus(this);
                    this.SetValue(Canvas.ZIndexProperty, App.NextMaxIndex);
                }
                else
                {
                    sNode.Fill = new SolidColorBrush(m_clrNormal);
                    sNodeShadow.Fill = new SolidColorBrush(m_clrShardow);
                }
            }
        }

        public void SetContent(string strText, string strComment)
        {
            this.txtLable.Text = strText;
            this.m_strComment = strComment;
        }

        public override Point GetCrossPoint(Point ptOuterPoint)
        {
            Point ptCenter = new Point(this.Width / 2, this.Height / 2);
            Point ptCross = Utility.GetRectangleCrossPoint(ptCenter, this.Width, this.Height, ptOuterPoint);
            return ptCross;
        }

        /// <summary>
        /// 尝试连接线条
        /// </summary>
        private void TryAddLink(Point ptLinkTo)
        {
            WorkflowBase itemEnd = App.theMainView.FindItemByPoint(ptLinkTo);
            if ((itemEnd != null) && (itemEnd != this))
            {
                if (App.theMainView.CheckNodeLink(this, itemEnd))
                {
                    FlowBeeline line = new FlowBeeline();
                    if (line.InitLine(this, itemEnd))
                    {
                        App.theMainView.AddFlowItem(line);
                    }
                }
            }
        }

        #region 事件处理

        private void Node_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            sNode.Width = this.Width;
            sNode.Height = this.Height;
            sNodeShadow.Width = this.Width;
            sNodeShadow.Height = this.Height;
            txtLable.SetValue(Canvas.TopProperty, (this.Height - txtLable.ActualHeight) / 2.0);
            txtLable.SetValue(Canvas.LeftProperty, (this.Width - txtLable.ActualWidth) / 2.0);
            App.theMainView.TryResize();

            if (this.OnControlMove != null)
            {
                this.OnControlMove(this);
            }
        }

        /// <summary>
        /// // 正在从中心的小圈圈开始拖动鼠标
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Center_OnMouseMove(object sender, MouseEventArgs e)
        {
            if (IsUseForToolBox)
            {
                return;
            }
            if (m_isTrackingMouseMove)
            {
                if (m_lineTracking == null)
                {
                    m_lineTracking = new ArrowLine();
                    this.LayoutRoot.Children.Add(m_lineTracking);
                    // 绘制形状的轮廓
                    m_lineTracking.Background = new SolidColorBrush(Colors.Green);
                    // 形状轮廓的粗细
                    m_lineTracking.StrokeThickness = 3.0;
                    DoubleCollection dashArray = new DoubleCollection();
                    dashArray.Add(1.0);
                    m_lineTracking.StrokeDashArray = dashArray;
                    this.SetValue(Canvas.ZIndexProperty, App.NextMaxIndex);
                    m_lineTracking.SetValue(Canvas.ZIndexProperty, 10);
                }
                if (m_lineTracking != null)
                {
                    m_lineTracking.Visibility = Visibility.Visible;
                    Point ptEndPoint = e.GetPosition(this);
                    m_lineTracking.StartPoint = this.GetCrossPoint(ptEndPoint);
                    m_lineTracking.EndPoint = ptEndPoint;
                }
            }
        }

        /// <summary>
        /// 在中心的小圈圈处松开了鼠标
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Center_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (IsUseForToolBox)
            {
                return;
            }
            if (m_isTrackingMouseMove)
            {
                e.Handled = true;
                m_isTrackingMouseMove = false;
                sNodeCenter.ReleaseMouseCapture();
                if (m_lineTracking != null)
                {
                    Point newPosition = e.GetPosition((UIElement)this.Parent);
                    m_lineTracking.Visibility = Visibility.Collapsed;
                    TryAddLink(newPosition);
                }
                this.IsFocus = true;
            }
        }


        /// <summary>
        /// 在中心的小圈圈处按下了鼠标
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Center_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (IsUseForToolBox)
            {
                return;
            }
            Debug.WriteLine("Center_OnMouseLeftButtonDown");
            e.Handled = true;
            this.IsFocus = true;
            // 检测双击处理
            if (m_doubleClickTimer.IsEnabled)
            {
                // 能走到这里，说明上一次的时间轴没有完成
                // 换句话说就是，在200毫秒之内，现在至少是第二次鼠标按下
                // 现在可以认为是鼠标双击！
                m_doubleClickTimer.Stop();
                // TODO: 进行双击处理
                this.OnDoubleClick();
            }
            else
            {
                // 开始时间轴处理，以200毫秒为期限
                m_doubleClickTimer.Start();
                m_isTrackingMouseMove = true;
                this.Cursor = Cursors.Hand;
                sNodeCenter.CaptureMouse();
            }
        }

        protected override void OnMouseEnter(MouseEventArgs e)
        {
            base.OnMouseEnter(e);
            this.IsMouseOver = true;
            this.Cursor = Cursors.Hand;
            if (!IsUseForToolBox && !IsFocus)
            {
                sNodeShadow.Fill = new SolidColorBrush(m_clrMouseOver);
                sNode.Fill = new SolidColorBrush(m_clrMouseOver);
            }
        }

        protected override void OnMouseLeave(MouseEventArgs e)
        {
            base.OnMouseLeave(e);
            this.IsMouseOver = false;
            this.Cursor = Cursors.Arrow;
            if (!IsUseForToolBox && !IsFocus)
            {
                sNodeShadow.Fill = new SolidColorBrush(m_clrShardow);
                sNode.Fill = new SolidColorBrush(m_clrNormal);
            }
        }

        #endregion

        public override bool IsUseForToolBox
        {
            get
            {
                return m_isUseForToolBox;
            }
            set
            {
                m_isUseForToolBox = value;
                if (m_isUseForToolBox)
                {
                    this.sNodeCenter.Visibility = Visibility.Collapsed;
                }
            }
        }

    }
}
